/*
 * @Author: 0x9DEFA478
 * @Date: 2025-07-26 19:36:11
 * @LastEditTime: 2025-09-15 21:19:02
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * 
 */
#ifndef hHMakeDependencyChain_HPP_
#define hHMakeDependencyChain_HPP_
#include <stdint.h>
#include <string>
#include "H_Pointer.hpp"
#include "Tree/H_Tree_RedBlack.hpp"
#include "H_Concurrency.hpp"


namespace HMake{
  
  class DependencyChain{

    public:
      class Item{
        public:
          using Pointer=H::PointerShare<Item>;

          enum class StatusEnum:int{
            Init=0,
            Running=1,
            Done=2
          };
        public:

          Item()noexcept;
          virtual ~Item()noexcept;

          void UpdateTargetStatus();
          void ForceSetNewExist();//该方法用作特殊用途
          H::size GetDependencyCount()const;
          bool IOExclusive()const noexcept{return ioexclusive;}
          bool SetIOExclusive(bool ioexclusive)noexcept{return this->ioexclusive=ioexclusive;}

          virtual int Run()=0;
          virtual void DoneEvent(bool IsUpdate)=0;
          virtual std::pair<bool,uint64_t> TargetStatus()=0;//返回更新时间, 数字越大代表越晚更新的, 0代表不作为依赖者的更新依据

        protected:
          bool targetValid;
          uint64_t targetLastUpdateTime;
          bool isIntoCount;
        private:
          using ItemCollection=H::Tree::RedBlack<Pointer,int>;
          using ChainMap=H::Tree::RedBlack<Item*,int>;
        private:
          StatusEnum status;
          ItemCollection itemCollection;
          ChainMap supportMap;
          ChainMap dependencyMap;
          ChainMap dependencyMap_Done;
          bool ioexclusive;
          
        friend class DependencyChain;
      };

    public:

      static int Run(Item::Pointer root,int MaxJob);
      static bool AddDependency(Item::Pointer& item,Item::Pointer& depItem);
      
    private:
      static Item* FindTask(Item* root);
      static void SetRun(Item* item);
      static int RunItem(Item* item,H::Lock& lock);
      static void SetDone(Item* item,bool IsUpdate);

  };

}


#endif //hHMakeDependencyChain_HPP_
